package cn.mdmm.service.impl.user;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.mdmm.common.MessageConstant;
import cn.mdmm.entity.response.ResponseBodyToOne;
import cn.mdmm.entity.system.SysRole;
import cn.mdmm.entity.system.SysRoleUser;
import cn.mdmm.entity.system.SysUser;
import cn.mdmm.entity.user.request.UserRequest;
import cn.mdmm.entity.user.request.UserUpdatePwdRequest;
import cn.mdmm.mapper.system.SysRoleUserMapper;
import cn.mdmm.mapper.user.UserMapper;
import cn.mdmm.service.memcached.MemcachedService;
import cn.mdmm.service.system.SysRoleService;
import cn.mdmm.service.user.UserCodeInfoService;
import cn.mdmm.service.user.UserLoginInfoService;
import cn.mdmm.service.user.UserService;
import cn.modoumama.common.exception.RequiredException;
import cn.modoumama.common.exception.ServiceException;
import cn.modoumama.common.response.Response;
import cn.modoumama.common.utils.DateUtils;
import cn.modoumama.common.utils.PasswordUtils;
import cn.modoumama.service.base.impl.BaseServiceImpl;

@Service
@Transactional
public class UserServiceImpl extends BaseServiceImpl<SysUser, Long>implements UserService {
	Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private MemcachedService memcachedClient;
	@Autowired
	private SysRoleUserMapper roleUsermapper;
	@Autowired
	private UserCodeInfoService userCodeInfoService;
	@Autowired
	UserLoginInfoService userLoginInfoService;
	@Autowired
	private SysRoleUserMapper sRoleUserMapper;
	@Autowired
	SysRoleService sysRoleService;
	@Autowired
	public void setMapper(UserMapper mapper) {
		setGenericMapper(mapper);
	}
	
	@Override
	public Integer insert(SysUser record){
		int count = 0;
		if(StringUtils.isBlank(record.getPhone())){
			throw new RequiredException("phone");
		}
		record.setUserStatus(1);
		record.setCreateTime(new Date());
		record.setUpdateTime(new Date());
		record.setUserPwd(PasswordUtils.getPassword(record.getUserName(), record.getUserPwd()));
		count = super.insert(record);
		return count;
	}
	@Override
	public Set<Long> getRoleIds(Long userId){
		SysRoleUser roleUser = new SysRoleUser();
		roleUser.setUserId(userId);
		List<SysRoleUser> roleUsers= roleUsermapper.findListByModel(roleUser);
   		//获取SysRole的id集合
		Set<Long> roleIds = new HashSet<>();
		for (SysRoleUser roleUser1 : roleUsers) {
			roleIds.add(roleUser1.getRoleId());
		}
		return roleIds;
	}
	
	@Override
	public Integer updateById(SysUser record){
		record.setUpdateTime(new Date());
		int flag = super.updateById(record);
		return flag;
	}
	
	@Override
	public void updateUserPwd(Long id,String userPwd,String newPwd,String confirmPwd) {
		SysUser user = new SysUser();
		user.setId(id);
		SysUser record = findObjectByModel(user);
		if(StringUtils.isNotBlank(userPwd)){
			userPwd = PasswordUtils.getPassword(record.getUserName(), userPwd);
			if(!userPwd.equals(record.getUserPwd())){
				throw new ServiceException(MessageConstant.PASSWORD_ERROR);
			}
		}
		
		if(newPwd.equals(confirmPwd)){
			newPwd = PasswordUtils.getPassword(record.getUserName(), newPwd);
			record.setUserPwd(newPwd);
			record.setUpdateTime(new Date());
			super.updateById(record);
			
		}else{
			throw new ServiceException(MessageConstant.NEW_PASSWORD_DIVERSE);
		}
	}
	
	@Override
	public  Integer removeByIds(Long[] userIds){
		int count = 0;
		for(Long userId : userIds){
			//删除用户
			removeById(userId);
			//删除用户和角色的绑定关系
			Map<String, Object> condition = new HashMap<String, Object>();
			condition.put("userId", userId);					
			count = roleUsermapper.deleteByCondition(condition);
		}
		return count;
	}

	@Override
	public Response checkUser(UserRequest request) {
		Response response = new Response();
		SysUser sysUser = copyValue(request);
		sysUser = findObjectByModel(sysUser);
		if(sysUser != null){
			throw new ServiceException(MessageConstant.USER_DOES_IS_EXIST);
		}
		return response;
	}

	@Override
	public ResponseBodyToOne register(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		String code = request.getCode();
		String phone = request.getPhone();
		String roleIdsStr = request.getRoleIds();
		if(StringUtils.isBlank(code)){
			throw new RequiredException("code");
		}
		if(StringUtils.isBlank(phone)){
			throw new RequiredException("phone");
		}
		
		if(StringUtils.isBlank(phone)){
			throw new RequiredException("phone");
		}
		
		if(StringUtils.isBlank(roleIdsStr)){
			throw new RequiredException("roleIds");
		}
		
		userCodeInfoService.verificationCode(phone, code);
		
		SysUser sysUser = new SysUser();
		if(StringUtils.isNotBlank(request.getUserName())){
			sysUser.setUserName(request.getUserName());
			sysUser = findObjectByModel(sysUser);
			if(sysUser != null){
				throw new ServiceException(MessageConstant.LOGIN_NAME_DOES_IS_EXIST);
			}
		}
		if(StringUtils.isNotBlank(request.getEmail())){
			sysUser.setEmail(request.getEmail());
			sysUser = findObjectByModel(sysUser);
			if(sysUser != null){
				throw new ServiceException(MessageConstant.EMAIL_DOES_IS_EXIST);
			}
		}
		
		//设置默认登陆名为手机号
		if(StringUtils.isBlank(request.getUserName())){
			request.setUserName(phone);
		}

		sysUser = copyValue(request);
		sysUser.setUserType(3);
		//设置默认密码为手机号
		if(StringUtils.isBlank(sysUser.getUserPwd())){
			sysUser.setUserPwd(phone);
		}
		insert(sysUser);

		if(roleIdsStr.trim().length()>0){
			roleIdsStr = roleIdsStr.trim();
			String[] roleIdsStrArr = roleIdsStr.split(",");
			Long[] roleIds = new Long[roleIdsStrArr.length];
			for (int i = 0; i < roleIdsStrArr.length; i++) {
				roleIds[i] = Long.parseLong(roleIdsStrArr[i]);
				if(roleIds[i]!= 4 && roleIds[i]!= 5){
					throw new RequiredException("roleIds");
				}
			}
			
			bindRoleUser(sysUser.getId(),roleIds);
		}
		
		
		responseBodyToOne.setData(getUser(sysUser));
		return responseBodyToOne;
	}

	@Override
	public ResponseBodyToOne login(UserRequest request) {
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = null;
		if(StringUtils.isNotBlank(request.getPhone())){
			if(StringUtils.isNotBlank(request.getCode())){
				userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
				user = new SysUser();
				user.setPhone(request.getPhone());
				user = findObjectByModel(user);
			}else if(StringUtils.isNotBlank(request.getUserPwd())){
				user= getUser(request.getPhone(), null, request.getUserPwd());
			}else{
				throw new RequiredException("code");
			}
		}else if(StringUtils.isBlank(request.getUserName())){
			throw new RequiredException("phone");
		}else if(StringUtils.isBlank(request.getUserPwd())){
				throw new RequiredException("userPwd");
		}else{
			user = getUser(request.getPhone(), request.getUserName(), request.getUserPwd());
		}
		
		
		
		if(user == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}else{
			List<SysRole> userRoles = getUserRole(user.getId());
			request.setUserId(user.getId());
			String token = userLoginInfoService.getToken(request);
			user.setToken(token);
			user.setUserRoles(userRoles);
			responseBodyToOne.setData(getUser(user));
			
			 // 查询该用户是否已登录，如果已登录则需要干掉之前的token，生成新的token
	        String oldToken = (String) memcachedClient.get(user.getId().toString());
	        if (StringUtils.isNotBlank(oldToken)) {
	        	memcachedClient.delete(oldToken);
	            // TODO: 发送推送将之前设备下线 2017/6/29 0029
	        }

	        // 设置token有效时间为30天
	        Integer express = 30 * DateUtils.TimeSecond.DAY;
	        //建立token和userId的对应关系（双向）
	        memcachedClient.set(user.getToken(), user.getId(),express);
	        memcachedClient.set(user.getId().toString(), user.getToken(),express);
		}
		return responseBodyToOne;
	}
	
	private SysUser getUser(String phone, String userName, String userPwd){
		SysUser user = new SysUser();
		if(StringUtils.isNotBlank(phone)){
			user.setPhone(phone);
		}else if(StringUtils.isNotBlank(userName)){
			user.setUserName(userName);
		}
		user = findObjectByModel(user);
		if(user == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		if(!user.getUserPwd().equals(PasswordUtils.getPassword(user.getUserName(), userPwd))){
			throw new ServiceException(MessageConstant.PASSWORD_ERROR);
		}
		
		return user;
	}

	private SysUser copyValue(UserRequest request){
		SysUser user = new SysUser();
		try {
			PropertyUtils.copyProperties(user, request);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			logger.info("");
		}
		
		return user;
	}

	@Override
	public Response updatePwd(UserUpdatePwdRequest request) {
		Response response = new Response();
		if(StringUtils.isBlank(request.getNewPwd())){
			throw new RequiredException("newPwd");
		}
		if(StringUtils.isBlank(request.getConfirmPwd())){
			throw new RequiredException("confirmPwd");
		}
		updateUserPwd(request.getUserId(), request.getUserPwd(), request.getNewPwd(), request.getConfirmPwd());
		return response;
	}
	
	@Override
	public Response resetPwd(UserUpdatePwdRequest request){
		Response response = new Response();
		if(StringUtils.isBlank(request.getPhone())){
			throw new RequiredException("phone");
		}
		
		if(StringUtils.isBlank(request.getCode())){
			throw new RequiredException("code");
		}
		
		if(StringUtils.isBlank(request.getNewPwd())){
			throw new RequiredException("newPwd");
		}
		if(StringUtils.isBlank(request.getConfirmPwd())){
			throw new RequiredException("confirmPwd");
		}
		
		SysUser sysUser = new SysUser();
		sysUser.setPhone(request.getPhone());
		sysUser = findObjectByModel(sysUser);
		if(sysUser == null){
			throw new ServiceException(MessageConstant.USER_DOES_NOT_EXIST);
		}
		updateUserPwd(sysUser.getId(), null, request.getNewPwd(), request.getConfirmPwd());

		//验证验证码
		userCodeInfoService.verificationCode(request.getPhone(), request.getCode());
		return response;
	}
	
	@Override
	public ResponseBodyToOne updateUser(UserRequest request){
		ResponseBodyToOne responseBodyToOne = new ResponseBodyToOne();
		SysUser user = new SysUser();
		user.setId(request.getUserId());
		user = findObjectByModel(user);
		user.setRealName(request.getRealName());
		user.setSex(request.getSex());
		user.setHeadImgUrl(request.getHeadImgUrl());
		updateById(user);
		responseBodyToOne.setData(getUser(user));
		return responseBodyToOne;
	}
	


	public void  bindRoleUser(Long userId,Long[] roleIds){
		List<Long> roleIdList = new ArrayList<Long>();
        for (int i=0; i<roleIds.length; i++) {
            if(!roleIdList.contains(roleIds[i])) {
            	roleIdList.add(roleIds[i]);
            }
        }
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("userId", userId);
		sRoleUserMapper.deleteByCondition(condition);
		for(int i=0;i<roleIdList.size();i++){
			Long roleId = roleIdList.get(i);
			SysRole role = sysRoleService.getRole(roleId);
			if(role == null || role.getRoleType()<1){
				continue;
			}
			if(roleId!=1){
				SysRoleUser record = new SysRoleUser();
				record.setRoleId(roleIds[i]);
				record.setUserId(userId);
				sRoleUserMapper.insertModel(record);
			}
		}
	}

	@Override
	public List<SysRole> getAllRole(Long userId) {
		SysUser sysUser = findById(userId);
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("roleType", sysUser.getUserType());
		List<SysRole> roles = sysRoleService.findModelsByCondition(condition);

   		//获取SysRole的id集合
		Set<Long> roleIds = getRoleIds(userId);
		//设置用户是否正在使用
   		for (Iterator<SysRole> iterator = roles.iterator(); iterator.hasNext();) {
   			SysRole role = iterator.next();
			if(roleIds.contains(role.getRoleId())){
				role.setIsUse(true);
   			}else{
   				role.setIsUse(false);
   			}
		}
		return roles;
	}
	
	public List<SysRole> getUserRole(Long userId) {
		List<SysRole> userRoles = new ArrayList<>();
   		//获取SysRole的id集合
		Set<Long> roleIds = getRoleIds(userId);
		//设置用户是否正在使用
   		for (Iterator<Long> iterator = roleIds.iterator(); iterator.hasNext();) {
   			Long roleId = iterator.next();
   			SysRole role = sysRoleService.getRole(roleId);
   			SysRole userRole = new SysRole();
   			userRole.setRoleId(roleId);
   			userRole.setRoleName(role.getRoleName());
   			userRoles.add(userRole);
		}
		return userRoles;
	}
	
	/** 接口返回数据前，去掉密码和创建时间*/
	private SysUser getUser(SysUser user){
		user.setUserPwd(null);
		user.setCreateTime(null);
		user.setUpdateTime(null);
		return user;
	}
}
